﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Threading;

namespace TekaMUD.Engine
{
	/// <summary>
	/// A blocking queue that stops the thread that tries to dequeue something until a new item is added to queue.
	/// </summary>
	/// <typeparam name="T">Type of the object stored in the queue.</typeparam>
	public class BlockingQueue<T> : Queue<T>
	{
		private object SyncRoot = new object();

		/// <summary>
		/// Remove all objects from the Queue.
		/// </summary>
		public new void Clear()
		{
			lock (SyncRoot)
			{
				base.Clear();
			}
		}

		/// <summary>
		/// Removes and returns the object at the beginning of the Queue.
		/// </summary>
		/// <returns>Object in queue.</returns>
		public new T Dequeue()
		{
			lock (SyncRoot)
			{
				while (base.Count == 0)
				{
					Monitor.Wait(SyncRoot);
				}
				return base.Dequeue();
			}
		}

		/// <summary>
		/// Adds an object to the end of the Queue.
		/// </summary>
		/// <param name="obj">Object to put in queue</param>
		public new void Enqueue(T obj)
		{
			lock (SyncRoot)
			{
				base.Enqueue(obj);
				Monitor.Pulse(SyncRoot);
			}
		}
	}
}
